package legumes.client.ui.basket.slate;


import java.util.ArrayList;
import java.util.List;

import legumes.client.evt.main.UserConnectedEvent;
import legumes.client.evt.main.UserConnectedEventHandler;
import legumes.client.evt.manager.EventBusManager;
import legumes.client.resources.PNResources;
import legumes.client.services.callbacks.GetSellSessionForCustomerCallback;
import legumes.client.services.util.rpc.RPCCallSequencer;
import legumes.client.ui.widgets.utils.Formatters;
import legumes.shared.domain.MenuCount;
import legumes.shared.domain.MenuItem;
import legumes.shared.domain.OnSaleProduct;
import legumes.shared.domain.Order;
import legumes.shared.domain.OrderPart;
import legumes.shared.domain.OrderPartMenuItem;
import legumes.shared.domain.Price;
import legumes.shared.domain.Product;
import legumes.shared.domain.Quantity;
import legumes.shared.domain.Stall;
import legumes.shared.domain.Unit;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HTMLTable.Cell;
import com.smartgwt.client.core.Function;
import com.smartgwt.client.widgets.WidgetCanvas;
import com.smartgwt.client.widgets.layout.VLayout;

public class BasketMainPanel extends VLayout {

	private FlexTable flexTableOutsideBasket;
//	private SellSessionForCustomer sellSessionForCustomer;
	private Stall stall;
	private OrderPart op;
	private BasketPanel basketPanel;
	private static final int productNumberPerLine = 5;
	private List<OnSaleProduct> onSaleProducts;
	private boolean isMarketEditMode;
	private Order order;
	
	public BasketMainPanel(boolean isMarketEditMode_) {
		super();
		isMarketEditMode = isMarketEditMode_;
		setWidth("700");
		setHeight100();
		setMembersMargin(5);  
        setLayoutMargin(10); 
        
        basketPanel = new BasketPanel(isMarketEditMode);
        flexTableOutsideBasket = new FlexTable();
        
        flexTableOutsideBasket.addClickHandler(new ClickHandler() {
			
			@Override
			public void onClick(ClickEvent event) {
				Cell cell = flexTableOutsideBasket.getCellForEvent(event);
				if( cell != null){
			        int receiverRowIndex = cell.getRowIndex();
			        int vegetableRowIndex = receiverRowIndex/2;//Because two rows represents a same product
			        int receiverColIndex = cell.getCellIndex();
			        int indexProduct = vegetableRowIndex*productNumberPerLine + receiverColIndex;
			        OnSaleProduct product = null;
			        if ( indexProduct>=0 && indexProduct < onSaleProducts.size() ){
			        	product = onSaleProducts.get(indexProduct);
			        } else {
			        	product = createNewOnSaleProduct();
			        }
			        
			        if( isMarketEditMode ){
			        	final ProductMarketEditionWindow pmew = new ProductMarketEditionWindow(
			        			stall,
			        			product, 
			        			new Function(){

									@Override
									public void execute() {
										displaySellSessionForCustomer();
									}
			        				
			        			});
			        	pmew.show();
			        	
			        } else {
			        	new ProductCustomerEditionWindow(product, stall, op).show();
			        }
				}
			}
		});
        
        bind();
		
        WidgetCanvas wc = new WidgetCanvas(flexTableOutsideBasket);
        setMembers(basketPanel, wc);
	}
	
	private void bind(){
		EventBusManager.getInstance().getEventBus().addHandler(
				UserConnectedEvent.TYPE, 
				new UserConnectedEventHandler() {
					
					@Override
					public void onUserConnected(UserConnectedEvent event) {
						if( (     order != null)
								&& (order.getCustomerId() != null
								|| order.getCustomerName() != null) ){
							order.setCustomerId(event.getCustomerDTO().getEmail());
							order.setCustomerId(event.getCustomerDTO().getName());
						}
						
					}
				}
		);
	}
	
	public void initData(Order order_, Stall stall_){
		stall = stall_;
		order = order_;
		if(!isMarketEditMode){
			op = initOrderData(order);	
		}
		basketPanel.initData(stall, op);
		
		displaySellSessionForCustomer();
	}
	
	private OnSaleProduct createNewOnSaleProduct(){
		OnSaleProduct osp = new OnSaleProduct();
		osp.setId(-1L);
		Price p = new Price();
		p.setAmount(0f);
		Quantity q = new Quantity();
		q.setUnitAsEnum(Unit.KG);
		q.setValue(1f);
		p.setQuantity(q);
		osp.setPrice(p);
		
		Product pr = new Product();
		pr.setName("Nouveau");
		
		osp.setProduct(pr);
		
		return osp;
	}
	
	private String getProductCss(String productName_, String varietyName_, String categoryName_){
		String catClass = "";
		if(categoryName_!=null && categoryName_.trim().length()>0){
			catClass = PNResources.PRODUCT_CATEGORY_CSS_PREFIX + categoryName_.toLowerCase();
		}
		
		String varClass = "";
		if(varietyName_!=null && varietyName_.trim().length()>0){
			varClass = PNResources.PRODUCT_VARIETY_CSS_PREFIX + varietyName_.toLowerCase();
		}
		
		String productClass = "";
		if(productName_!=null && productName_.trim().length()>0){
			productClass = PNResources.PRODUCT_NAME_CSS_PREFIX + productName_.toLowerCase();
		}
		
		return  PNResources.PRODUCT_NAME_CSS_PREFIX + "commonVegetable " 
				+ catClass + " "
				+ varClass + " "
				+ productClass + " "
				;
	}
	
	private void updateFlexTableOutsideBasketCell(int rowIndex_, int colIndex_, String glueCagette_,
			String productName_, String varietyName_, String categoryName_){
		flexTableOutsideBasket.setHTML(rowIndex_, colIndex_, 
				"<div class=\"cursorHand " + glueCagette_ + "\">" +
				"<div class=\"borderCagette\">" +								
				"<div class=\"" + getProductCss(productName_, varietyName_, categoryName_)
				+ "\">" +
				"</div></div></div>"
		);
	}
	
	protected void displaySellSessionForCustomer() {
		flexTableOutsideBasket.removeAllRows();
		
		onSaleProducts = stall.getOnSaleProducts();
		int sizeOnSaleProducts = onSaleProducts.size();
		if( isMarketEditMode ){
			sizeOnSaleProducts++;
		}
		OnSaleProduct [] onSaleProductAr = new OnSaleProduct[sizeOnSaleProducts];
		onSaleProducts.toArray(onSaleProductAr);
		if( isMarketEditMode ){
			onSaleProductAr[onSaleProductAr.length-1] = createNewOnSaleProduct();
		}
		
		int rowIndex=0;
		
		int productPerLineIndex = 0;
		String [] productsNamePerLineAr = new String[productNumberPerLine];
		String [] productsVarietyNamePerLineAr = new String[productNumberPerLine];
		String [] productsCategoryNamePerLineAr = new String[productNumberPerLine];
		String glueCagette = "glueCagette";
    	for (OnSaleProduct p : onSaleProductAr) {
			try{	
				glueCagette = "glueCagette";
				if(productPerLineIndex>=productNumberPerLine){
					productPerLineIndex=0;
					rowIndex++;
					
					for(productPerLineIndex=0;productPerLineIndex<productNumberPerLine;productPerLineIndex++){
						glueCagette = "glueCagette";
						if(productPerLineIndex==0){
							glueCagette="";
						}
						updateFlexTableOutsideBasketCell(rowIndex, productPerLineIndex, glueCagette,
								productsNamePerLineAr[productPerLineIndex],
								productsVarietyNamePerLineAr[productPerLineIndex],
								productsCategoryNamePerLineAr[productPerLineIndex] );
//						flexTableOutsideBasket.setHTML(rowIndex, productPerLineIndex, 
//								"<div class=\"cursorHand " + glueCagette + "\">" +
//								"<div class=\"borderCagette\">" +								
//								"<div class=\"" + PNResources.PRODUCT_NAME_CSS_PREFIX + "commonVegetable " 
//								+ PNResources.PRODUCT_NAME_CSS_PREFIX + productsNamePerLineAr[productPerLineIndex].toLowerCase() + " "
//								+ PNResources.PRODUCT_VARIETY_CSS_PREFIX + productsVarietyNamePerLineAr[productPerLineIndex].toLowerCase() + " "
//								+ PNResources.PRODUCT_CATEGORY_CSS_PREFIX + productsCategoryNamePerLineAr[productPerLineIndex].toLowerCase() + " "
//								+ "\">" +
//								"</div></div></div>"
//						);
					}
					productPerLineIndex=0;
					rowIndex++;
				}
				
				if(productPerLineIndex==0){
					glueCagette="";
				}
				String price = Formatters.formatPrice(p.getPrice(), true);
				String name = p.getProduct().getName();
				String variety = "";
				String category = "";
				if(p.getProduct().getProductVariety()!=null){
					variety = p.getProduct().getProductVariety().getName();
					if(p.getProduct().getProductVariety().getProductCategory()!=null){
						category = p.getProduct().getProductVariety().getProductCategory().getName();
					}
				}
				
				String quantity = new Float(p.getPrice().getQuantity().getValue()).toString();
				if(p.getPrice().getQuantity().getValue()==1){
					quantity="";
				}
				String appendSpacesToProductName = "";
				if(name.length()<=8){
					appendSpacesToProductName = "&nbsp;&nbsp;&nbsp;";
				}
				String quantityUnit = p.getPrice().getQuantity().getUnitAsEnum().getDisplayName();
				String priceTxt = price + " / " + quantity + quantityUnit;
				String appendSpacesToPriceTxt = "";
				if(priceTxt.length()<=16){
					appendSpacesToPriceTxt = "&nbsp;&nbsp;&nbsp;";
				}
				flexTableOutsideBasket.setHTML(rowIndex, productPerLineIndex, 
						"<div class=\"cursorHand " + glueCagette + "\">" +
						"<div class=\"slate\">" +
						"<div id=\"shoppingChartGreen." + name + "\" class=\"productInChartGreenFlag \"></div>" +
						"<div class=\"slateTxt\">" + appendSpacesToProductName + "<span class=\"txtUnderline\">" + name + "</span> <BR/>" +
						appendSpacesToPriceTxt + "<span class=\"priceTxt\">" + priceTxt + "</span>" +
						"</div></div></div>"
				);
				productsNamePerLineAr[productPerLineIndex]=name;
				productsVarietyNamePerLineAr[productPerLineIndex]=variety;
				productsCategoryNamePerLineAr[productPerLineIndex]=category;
				
				productPerLineIndex++;
			} catch (NullPointerException e_) {
				GWT.log("Err on displaySellSessionForCustomer ", e_);
			}
		}
    	
		int nbProductLeft = productPerLineIndex;
		productPerLineIndex=0;
		rowIndex++;
		
		for(productPerLineIndex=0;productPerLineIndex<nbProductLeft;productPerLineIndex++){
			glueCagette = "glueCagette";
			if(productPerLineIndex==0){
				glueCagette="";
			}
			updateFlexTableOutsideBasketCell(rowIndex, productPerLineIndex, glueCagette,
					productsNamePerLineAr[productPerLineIndex],
					productsVarietyNamePerLineAr[productPerLineIndex],
					productsCategoryNamePerLineAr[productPerLineIndex] );
//			flexTableOutsideBasket.setHTML(rowIndex, productPerLineIndex, 
//					"<div class=\"cursorHand " + glueCagette + "\">" +
//					"<div class=\"borderCagette\">" +								
//					"<div class=\"" + PNResources.PRODUCT_NAME_CSS_PREFIX + "commonVegetable " + PNResources.PRODUCT_NAME_CSS_PREFIX + productsNamePerLineAr[productPerLineIndex].toLowerCase() + "\">" +
//					"</div></div></div>"
//			);
		}
	}
	
	
	private OrderPart initOrderData(Order order_){
		if( order_.getOrderParts() == null ){
			order_.setOrderParts(new ArrayList<OrderPart>(1));
		}
		OrderPart op = null;
		if(order_.getOrderParts().size()<=0){
			op = createOrderPart(order.getDate());
			order_.getOrderParts().add( op );
		} else {
			//TODO SMA Manage Multiples OP
			op = order_.getOrderParts().get(0);
		}
		
//		if( sellSessionForCustomer_.getOrder().getOrderParts().size()<=0){
//			
//		} else {
//			
//		}
		return op;
	}
	
	private OrderPart createOrderPart(
			long creationDate_){
		OrderPart op = new OrderPart();
		op.setId(creationDate_);
		
		OrderPartMenuItem opmi = new OrderPartMenuItem();
		opmi.setId(creationDate_);
		opmi.setMenu(stall.getMenu());
		opmi.setMenuCount(MenuCount.ONE_MENU);
		opmi.setRemovedMenuItems(new ArrayList<MenuItem>());
		op.setOrderPartMenuItem(opmi);
		
		return op;
	}

	public void refreshData() {
		final GetSellSessionForCustomerCallback c = new GetSellSessionForCustomerCallback();
		  RPCCallSequencer callSequencer = new RPCCallSequencer(
			"Chargement en cours...");
		  callSequencer.addCall(c);
			callSequencer.addRunnable(new Runnable() {
				public void run() {
					initData(c.getSellSessionForCustomer().getOrder(),c.getSellSessionForCustomer().getStall() );
				}
			});
			callSequencer.callSequence();
	}

	
}
